<template>
  <div class="function-btn-com">
    <div class="left-btn" :class="{ disable: isVisitor || isLock }">
      <a-tooltip placement="top">
        <template slot="title">
          <span v-if="!pipelineRunStatus">按住ctrl键多选可部分执行</span>
          <span v-else>停止</span>
        </template>
        <!-- <div :class="!isVisitor && !isLock ? 'btn' : 'btn-disable'"> -->
        <div v-if="isVisitor || isLock" class="btn-disable">
          <div class="btn-span">
            <a-icon-font type="iconyunhang" />
            <span class="function-run-text">执行</span>
          </div>
        </div>
        <div v-else class="btn">
          <div
            v-if="!pipelineRunStatus"
            class="btn-span"
            @click="pipelineRunning"
          >
            <a-icon-font type="iconyunhang" />
            <span class="function-run-text">执行</span>
          </div>
          <div v-else class="btn-span" @click="pipelineStop">
            <a-icon-font type="icontingzhi" />
            <span class="function-run-text">停止</span>
          </div>
        </div>
      </a-tooltip>

      <span class="divider"></span>
      <div v-for="(tip, index) in functionList" :key="index">
        <span v-if="tip.tooltip === 'diver'" class="divider"></span>
        <a-tooltip v-else placement="top">
          <template slot="title">
            <span>{{ tip.tooltip }}</span>
          </template>
          <div
            :class="
              !isVisitor && !isLock
                ? 'btn function-btn-spacing'
                : 'btn-disable function-btn-spacing'
            "
            @click="clickFunction(tip.click)"
          >
            <a-icon-font :type="tip.icon" />
          </div>
        </a-tooltip>
      </div>
    </div>

    <div class="right-btn" :class="{ disable: isVisitor || isLock }">
      <div v-for="(tip, index) in rightFuncList" :key="'right' + index">
        <span v-if="tip.tooltip === 'diver'" class="divider"></span>
        <a-tooltip v-else placement="top">
          <template slot="title">
            <span>{{ tip.tooltip }}</span>
          </template>
          <div
            :class="{
              'btn function-btn-spacing': !isVisitor && !isLock,
              'btn-disable function-btn-spacing': isVisitor || isLock,
              select: tip.select,
            }"
            @click="clickFunction(tip.click)"
          >
            <a-icon-font :type="tip.icon" />
          </div>
        </a-tooltip>
      </div>

      <!--  保存屏幕快照  -->
      <a-popconfirm
        placement="bottom"
        ok-text="确定"
        cancel-text="取消"
        :visible="overSaveVisible"
        @cancel="cancelSave"
        @confirm="overSave"
      >
        <a-icon-font slot="icon" type="iconweiwanpeizhi"></a-icon-font>
        <template slot="title">
          <span>版本库已满，是否删除最早版本保存当前版本？</span>
        </template>
      </a-popconfirm>
    </div>

    <node-delete-confirm
      :visible="deleteConfirmVisible"
      :nodes="multiWithSelectNodes"
      :is-clear="isClear"
      @confirm="confirm"
      @cancel="cancelDelete"
    />
  </div>
</template>

<script lang="ts">
import { Component, Vue, Watch } from 'vue-property-decorator'
import DataViewStore from '@/store/modules/dataview'
import NodeDeleteConfirm from '@/components/studio/data/NodeDeleteConfirm.vue'
import {
  clearProjectById,
  batchForbidden,
  batchUnForbidden,
  batchDelete,
  batchCopy,
  undo,
  redo,
} from '@/api/task'

@Component({
  components: { NodeDeleteConfirm },
})
export default class PipelineFunction extends Vue {
  public projectId: number | null = null
  public deleteConfirmVisible: boolean = false // 确认删除节点弹窗
  public isClear: boolean = false
  public keyCode1: number | null = null
  public keyCode2: number | null = null
  public keyCode3: number | null = null
  // public pipelineRunStatus: boolean = false // pipeline是否执行

  public functionList: any[] = [
    { tooltip: '清空Pipeline', click: 'clearPipeline', icon: 'iconqingkong' },
    { tooltip: '批量复制', click: 'bulkCopy', icon: 'iconfuzhijiedian' },
    { tooltip: '批量启用', click: 'bulkUnForbidden', icon: 'iconqiyong' },
    { tooltip: '批量禁用', click: 'bulkForbidden', icon: 'iconjinyong' },
    { tooltip: '批量删除', click: 'bulkDelete', icon: 'iconicon-beifen5' },
    { tooltip: 'diver', click: '', icon: '' },
    { tooltip: 'undo', click: 'undo', icon: 'iconhoutui2' },
    { tooltip: 'redo', click: 'redo', icon: 'iconqianjin1' },
  ]

  public rightFuncList: any[] = [
    {
      tooltip: '节点对比',
      click: 'toggleComparison',
      icon: 'iconduibi1',
      select: false,
    },
    {
      tooltip: '版本查看',
      click: 'toggleHistory',
      icon: 'iconbanbenkuaizhao',
      select: false,
    },
    {
      tooltip: '保存快照，快捷键：Control+Shift+S',
      click: 'toggleScreenShot',
      icon: 'iconbaocun',
      select: false,
    },
    { tooltip: 'diver', click: '', icon: '' },
    {
      tooltip: '日志',
      click: 'toggleRunLog',
      icon: 'iconrizhi',
      select: false,
    },
    {
      tooltip: '可视化收藏',
      click: 'toggleFavorite',
      icon: 'iconshoucang2',
      select: false,
    },
  ]

  public get isVisitor() {
    return DataViewStore.isVisitor
  }

  public get isLock() {
    return DataViewStore.getLock
  }

  public get historyStatus() {
    return DataViewStore.getHistoryStatus
  }

  public get favoriteStatus() {
    return DataViewStore.getFavoriteStatus
  }

  public get selectFunctionIndex() {
    return DataViewStore.getSelectFunctionIndex
  }

  @Watch('selectFunctionIndex')
  public selectFunctionIndexChange(newV: number, oldV: number) {
    if (oldV) {
      this.rightFuncList[oldV].select = false
    }
    if (newV) {
      this.rightFuncList[newV].select = true
    }
  }

  @Watch('historyStatus')
  public async historyStatusChange() {
    this.rightFuncList[1].select = this.historyStatus
  }

  @Watch('favoriteStatus')
  public async favoriteStatusChange() {
    this.rightFuncList[5].select = this.favoriteStatus
  }

  // 是否覆盖版本弹框显示
  public get overSaveVisible() {
    return DataViewStore.getOverSaveVisible
  }

  /**
   * 选择的节点 + selectNodeId
   */
  public get multiWithSelectNodes() {
    return DataViewStore.multiWithSelectNodes
  }
  // pipeline Id
  public get pipelineId() {
    return DataViewStore.getPipelineId
  }

  public get pipelineRunStatus() {
    return DataViewStore.executionStart
  }

  public get enableVRPanelRecommend() {
    return DataViewStore.enableVRPanelRecommend
  }

  public get actionArea() {
    return DataViewStore.ActionArea
  }

  public mounted() {
    this.projectId = Number(this.$route.params.id)
    document.addEventListener('keyup', this.globalKeyUp)
    document.addEventListener('keydown', this.globalKeyDown)
    // DataViewStore.getUserRole({ projectId: this.projectId })
  }

  public beforeDestroy() {
    document.removeEventListener('keyup', this.globalKeyUp)
    document.removeEventListener('keydown', this.globalKeyDown)
  }

  /**
   * 快捷键监听  ArrowDown: 下, ArrowUp: 上,  Enter: enter
   * @param $event
   */
  public globalKeyDown($event: KeyboardEvent) {
    if (this.isVisitor || this.isLock) {
      return
    }
    if (this.actionArea === 'pipeline') {
      if ($event.key === 'Control' || $event.key === 'Meta') {
        this.keyCode1 = 1
      }
      if ($event.key === 'z' || $event.key === 'Z') {
        this.keyCode2 = 2
      }
      if ($event.key === 'Shift') {
        this.keyCode3 = 3
      }
      if (this.keyCode1 === 1 && this.keyCode2 === 2) {
        if (this.keyCode3 === 3) {
          this.redoFunc()
        } else if (this.keyCode3 === null) {
          this.undoFunc()
        }
      }
    }
  }
  public globalKeyUp($event: KeyboardEvent) {
    if (this.isVisitor || this.isLock) {
      return
    }
    if (this.actionArea === 'pipeline') {
      // 列表弹框出现
      const isMac = /macintosh|mac os x/i.test(navigator.userAgent)
      if ($event.key === 'Backspace') {
        if (isMac) {
          this.bulkDelete()
        }
      }
      if ($event.key === 'Delete') {
        this.bulkDelete()
      }
      if ($event.key === 'Enter' && this.deleteConfirmVisible) {
        this.confirm()
      }
      if ($event.key === 'Control' || $event.key === 'Meta') {
        this.keyCode1 = null
        this.keyCode2 = null
      }
      if ($event.key === 'z' || $event.key === 'Z') {
        this.keyCode2 = null
      }
      if ($event.key === 'Shift') {
        this.keyCode2 = null
        this.keyCode3 = null
      }
    }
  }

  // 更新画布
  public async getAllNodes() {
    const parameters = {
      id: this.projectId,
      pipelineId: DataViewStore.getPipelineId,
    }
    await DataViewStore.queryPipelineNodes(parameters)
  }

  // 覆盖版本库
  public overSave() {
    DataViewStore.setOverSaveVisible(false)
    this.$emit('over-save')
  }

  // 取消保存
  public cancelSave() {
    DataViewStore.setOverSaveVisible(false)
  }

  /**
   * pipeline 执行
   */
  public pipelineRunning() {
    // DataViewStore.setExecutionCompletionType(!this.pipelineRunStatus)
    // DataViewStore.setExecutionCompletionType(this.pipelineRunStatus)

    this.$emit('pipeline-run')
  }

  /**
   * pipeline 停止
   */
  public async pipelineStop() {
    this.$message.info('停止中')
    this.$emit('pipeline-stop')
  }

  // 多个功能 统一点击入口
  public clickFunction(functionName: string) {
    if (this.isVisitor || this.isLock) {
      return
    }
    switch (functionName) {
      case 'clearPipeline':
        this.clearPipeline()
        break
      case 'bulkCopy':
        this.bulkCopy()
        break
      case 'bulkUnForbidden':
        this.bulkUnForbidden()
        break
      case 'bulkForbidden':
        this.bulkForbidden()
        break
      case 'bulkDelete':
        this.bulkDelete()
        break
      case 'undo':
        this.undoFunc()
        break
      case 'redo':
        this.redoFunc()
        break
      case 'toggleComparison':
        this.toggleComparison()
        break
      case 'toggleHistory':
        this.toggleHistory()
        break
      case 'toggleScreenShot':
        this.toggleScreenShot()
        break
      case 'toggleRunLog':
        this.toggleRunLog()
        break
      case 'toggleFavorite':
        this.toggleFavorite()
        break
      default:
        break
    }
  }

  /**
   * 清空画布
   */
  public clearPipeline() {
    if (DataViewStore.pipelineNodes.length > 0) {
      this.isClear = true
      if (DataViewStore.pipelineDeleteConfirm) {
        this.deleteConfirmVisible = true
      } else {
        this.confirmClearNode()
      }
    } else {
      this.$message.warning('当前画布为空, 无需清空 !')
    }
  }

  // 确认清空 pipeline
  public async confirmClearNode() {
    const parameters = {
      id: this.projectId,
    }
    const response: any = await clearProjectById({ data: parameters })
    if (response.data.code === 100) {
      this.dealStore([])
      await this.getAllNodes()
      this.$message.success('清空 pipeline 成功 !', 0.5)
      this.deleteConfirmVisible = false
      this.isClear = false
    } else if (response.data.code === 500) {
      this.$message.warning(response.data.tips)
    }
  }

  /**
   * 处理 store 中的 selectNode 和清空选择的节点， 在清空 pipeline ,和批量删除使用
   */
  public dealStore(nodes: any) {
    DataViewStore.deleteNodeUpdateSelectNode(nodes)
    DataViewStore.clearMultiSelectNodeArray()
  }

  // 确认清空画布还是确认清空选择的节点
  public confirm() {
    if (this.isClear) {
      this.confirmClearNode()
    } else {
      this.confirmDeleteNode()
    }
  }

  // 取消删除/清空
  public cancelDelete() {
    this.deleteConfirmVisible = false
    setTimeout(() => {
      this.isClear = false
    }, 500)
  }

  /**
   * 批量删除
   */
  public bulkDelete() {
    if (document.activeElement?.tagName === 'INPUT') {
      return
    }
    if (this.multiWithSelectNodes.length > 0) {
      if (DataViewStore.pipelineDeleteConfirm) {
        this.deleteConfirmVisible = true
      } else {
        this.confirmDeleteNode()
      }
    } else {
      this.$message.warning('请选择节点后删除 !')
    }
  }

  /**
   * 确认批量删除节点
   */
  public async confirmDeleteNode() {
    const nodeIds: string = this.multiWithSelectNodes
      .map((node: any) => node.id)
      .toString()
    const parameters = {
      ids: nodeIds,
      pipelineId: this.pipelineId,
      projectId: this.projectId,
    }
    const response: any = await batchDelete({ data: parameters })
    if (response.data.code === 100) {
      this.dealStore(this.multiWithSelectNodes)
      await this.getAllNodes()
      this.$message.success('删除节点成功 !', 0.5)
      this.deleteConfirmVisible = false
    } else if (response.data.code === 500) {
      this.$message.warning(response.data.tips)
    }
  }

  /**
   * 批量复制
   */
  public async bulkCopy() {
    if (this.multiWithSelectNodes.length > 0) {
      const nodeIds: string = this.multiWithSelectNodes
        .map((node: any) => node.id)
        .toString()
      const parameters = {
        ids: nodeIds,
        pipelineId: this.pipelineId,
        projectId: this.projectId,
      }
      const response: any = await batchCopy({ data: parameters })
      if (response.data.code === 100) {
        await this.getAllNodes()
        this.$message.success('复制节点成功 !', 0.5)
        this.deleteConfirmVisible = false
      } else if (response.data.code === 500) {
        this.$message.warning(response.data.tips)
      }
    } else {
      this.$message.warning('请选择节点后复制 !')
    }
  }

  /**
   * 批量禁用
   */
  public async bulkForbidden() {
    if (this.multiWithSelectNodes.length > 0) {
      const nodeIds: string = this.multiWithSelectNodes
        .map((node: any) => node.id)
        .toString()
      const parameters = {
        ids: nodeIds,
        pipelineId: this.pipelineId,
        projectId: this.projectId,
      }
      const response: any = await batchForbidden({ data: parameters })
      if (response.data.code === 100) {
        await this.getAllNodes()
        this.$message.success('禁用节点成功 !', 0.5)
      } else if (response.data.code === 500) {
        this.$message.warning(response.data.tips)
      }
    } else {
      this.$message.warning('请选择节点后批量禁用 !')
    }
  }

  /**
   * 批量启用
   */
  public async bulkUnForbidden() {
    if (this.multiWithSelectNodes.length > 0) {
      const nodeIds: string = this.multiWithSelectNodes
        .map((node: any) => node.id)
        .toString()
      const parameters = {
        ids: nodeIds,
        pipelineId: this.pipelineId,
        projectId: this.projectId,
      }
      const response: any = await batchUnForbidden({ data: parameters })
      if (response.data.code === 100) {
        await this.getAllNodes()
        this.$message.success('启用节点成功 !', 0.5)
      } else if (response.data.code === 500) {
        this.$message.warning(response.data.tips)
      }
    } else {
      this.$message.warning('请选择节点后批量启用 !')
    }
  }

  /**
   * undo
   */
  public undoFunc() {
    setTimeout(() => {
      this.editFunction('undo')
    }, 100)
  }

  public async editFunction(operate: string) {
    const parameters = {
      pipelineId: this.pipelineId,
      projectId: this.projectId,
    }
    const response: any =
      operate === 'undo'
        ? await undo({ data: parameters })
        : await redo({ data: parameters })
    if (response.data.code === 100) {
      await this.getAllNodes()
      this.refreshSelectNode()
      this.$message.success(
        operate === 'undo' ? '撤销成功 !' : '恢复成功！',
        0.5
      )
    } else if (response.data.code === 500) {
      this.$message.warning(response.data.tips)
    }
  }

  private refreshSelectNode() {
    const { selectNode, pipelineNodes } = DataViewStore
    if (selectNode) {
      const newNode = pipelineNodes.filter(
        (item) => item.id === selectNode.id
      )[0]
      DataViewStore.setSelectNode(newNode)
      if (newNode && +newNode.type === 5) {
        // 清洗节点获取清洗历史
        DataViewStore.getHistoryList()
      }
      if (!newNode) {
        DataViewStore.setVRPanelShow(false)
      }
    }
  }
  /**
   * redo
   */
  public redoFunc() {
    setTimeout(() => {
      this.editFunction('redo')
    }, 100)
  }

  /**
   * 日志窗口 开关
   */
  public toggleRunLog() {
    this.$emit('toggle-log')
  }
  /**
   * 收藏窗口 开关
   */
  public toggleFavorite() {
    this.$emit('toggle-favorite')
  }

  /**
   * 版本快照历史 开关
   */
  public toggleHistory() {
    this.$emit('toggle-history')
  }

  private get comparisonStatus() {
    return DataViewStore.comparisonStatus
  }

  /**
   * 保存屏幕快照
   *  */

  public toggleScreenShot() {
    this.$emit('toggle-screenshot')
  }

  /**
   * 打开可视化对比 header
   */
  public toggleComparison() {
    console.log(this.comparisonStatus)
    // DataViewStore.setComparisonStatus(!this.comparisonStatus)
    DataViewStore.setComparisonStatus(true)
  }
}
</script>

<style scoped lang="less">
/* 功能按钮 */
.function-btn-com {
  align-items: center;
  background-color: #fff;
  border-bottom: 1px solid #d8d8d8;
  box-sizing: border-box;
  display: flex;
  height: 38px;
  justify-content: space-between;
  padding: 0 10px;
  width: 100%;

  .left-btn,
  .right-btn {
    align-items: center;
    display: flex;

    .select {
      background-color: rgba(105, 115, 255, 0.1);
      color: #6973ff !important;
    }

    .btn {
      align-items: center;
      border-radius: 2px;
      color: rgb(93, 99, 126);
      cursor: pointer;
      display: flex;
      font-size: 16px;
      padding: 4px;
      position: relative;
      user-select: none;

      &:hover {
        background-color: rgba(105, 115, 255, 0.1);
        color: #6973ff;
      }

      .btn-divider {
        border-right: 1px solid #5d637e;
        height: 16px;
        margin: 0 5px;
        width: 1px;
      }
    }

    .btn-disable {
      align-items: center;
      border-radius: 2px;
      cursor: not-allowed;
      display: flex;
      font-size: 16px;
      // opacity: 0.45;
      padding: 4px;
      position: relative;
      user-select: none;
    }

    .btn-span {
      align-items: center;
      display: flex;

      span {
        font-size: 14px;
        margin-left: 5px;
        margin-right: 0;
      }
    }

    .divider {
      border-right: 1px solid #5d637e;
      height: 16px;
      margin: 0 5px;
      width: 1px;
    }

    .divider2 {
      border-right: 1px solid #5d637e;
      height: 16px;
      margin-left: 5px;
      width: 1px;
    }

    .function-btn-spacing {
      margin: 0 5px;
    }

    .function-btn-spacing-right {
      margin-right: 5px;
    }

    .btn-recommend.disable {
      filter: grayscale(100%);
      opacity: 0.6;
    }
  }

  // .left-btn {
  //   .btn {
  //     margin-right: 2px;
  //   }

  //   .function-run-text {
  //     margin-right: 10px;
  //   }
  // }
}

.disable {
  cursor: not-allowed;
  opacity: 0.45;
}
</style>
